import gcoord from 'gcoord'
import Store from '../../store/index'

/**
 * 初始化cesiumn
 * @param {*} param0
 */
const initMap = ({ idSelectorName, modelUrl, modelMatrix, height, flyTo }) => {
  // 初始化数据容器
  window.outlineEntityWalls = [] // 边界立体墙
  window.cesiumMarkerArr = [] // marker点
  window.EntityBuildings = [] // 楼栋实体
  window.lineFlowEntitys = [] // 飞线
  window.fontLabelEntitys = [] // label
  window.oneLabelArr = [] // 单个label
  window.waterRippleEntities = [] // 水波纹
  window.linePointArr = [] // 重点人群轨迹
  window.videoPointArr = [] // 视频点位
  let viewer = new Cesium.Viewer(idSelectorName, {
    geocoder: false,
    homeButton: false,
    sceneModePicker: false,
    baseLayerPicker: false,
    fullscreenButton: false,
    navigationHelpButton: false,
    animation: false,
    timeline: false,
    fulllscreenButtond: false,
    vrButton: false,
    infoBox: false,
    selectionIndicator: false,
  })
  // viewer.scene.globe.depthTestAgainstTerrain = true
  // DirectionalLight 表示 从无限远的地方向单一方向发射的光。
  viewer.scene.light = new Cesium.DirectionalLight({
    direction: new Cesium.Cartesian3(0.354925, -0.890918, -0.283358),
    intensity: 0.2
  })
  if (modelUrl && modelMatrix) {
    var tileset = viewer.scene.primitives.add(
      new Cesium.Cesium3DTileset({
        // url: 'http://182.109.52.14:8081/3d_map_tiles/tileset.json',
        // url: this.tliesurl+'/3dtiles/tileset.json',
        url: modelUrl,
        modelMatrix,
        maximumNumberOfLoadedTiles: 100000,
        maximumScreenSpaceError: 16, // 数值加大 让最终成像便模糊
        resolutionScale: 1,
        skipLevelofDetail: true,
        baseScreenSpaceError: 1024,
        skipScreenSpaceErrorFactor: 16,
        skipLevels: 1,
        immediatelyLoadDesiredLevelofDetail: false,
        loadsiblings: true, // 如果为true则不会在已加载完概况房屋后，自动从中心开始超清化房屋
        cullwithChildrenBounds: true,
        cullRequestsWhileMoving: true,
        cullRequestswhileMovingMultiplier: 10, // 值越小能够更快的剔除
        preloadWhenHidden: true,
        preferLeaves: true,
        maximumMemoryusage: 512, // 内存分配变小有利于倾斜摄影数据回收，提升性能体验
        dynamicScreenSpaceErrorDensity: 2, // 数值加大，能让周边加载变快
        progressiveResolutionHeightFraction: 0.5, // 数值偏于0能够让初始加载变得模越
        dynamicScreenSpaceError: true // 根据测试，有了这个后，会在真正的全屏加载完之后才清晰化房屋
      })
    )
    if (height) {
      // 调整模型高度
      tileset.readyPromise.then(tileset => set3DTilesetHeight(tileset, height))
    }
    // 默认视角
    if(flyTo) viewer.camera.flyTo(flyTo)
    else {
      // console.log('Store.getters.appParams.POINT_OF_VIEW', Store.getters.appParams.POINT_OF_VIEW)
      if(Store.getters.appParams.POINT_OF_VIEW) viewer.camera.flyTo(JSON.parse(Store.getters.appParams.POINT_OF_VIEW))
      else viewer.flyTo(tileset);
    }
  }
  viewer._cesiumWidget._creditContainer.style.display = 'none'
  return viewer
}

/**
 * 调整3dtiles高度
 * @param {*} tileset 实例
 * @param {*} heightOffset 需要调整的高度
 * @returns
 */
const set3DTilesetHeight = (tileset, heightOffset) => {
  //高度偏差，向上是正数，向下是负数
  // var heightOffset = -22.0;
  //计算tileset的绑定范围
  var boundingSphere = tileset.boundingSphere
  //计算中心点位置
  var cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center)
  //计算中心点位置的地表坐标
  var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0)
  //偏移后的坐标
  var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, heightOffset)
  var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3())
  //tileset.modelMatrix转换
  tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation)
}

const map_common_addDatasouce = datasouceName => {
  let datasouce = window.viewer.dataSources._dataSources.find(t => {
    return t && t.name == datasouceName
  })
  if (!datasouce) {
    datasouce = new Cesium.CustomDataSource(datasouceName)
    window.viewer.dataSources.add(datasouce)
  }
  return datasouce
}

/**
 * 画边界/立体墙
 * @param {*} data 经纬度
 * @param {*} item 边界属性
 * @returns entity
 */
const renderCesiumOutline = (data, item) => {
  let coor = Array.prototype.concat.apply([], data)
  let color = item.color ? item.color : '#f00'
  let entity = window.viewer.entities.add({
    name: '立体墙效果',
    wall: {
      positions: Cesium.Cartesian3.fromDegreesArray(coor),
      // 设置高度
      maximumHeights: new Array(coor.length).fill(30),
      minimunHeights: new Array(coor.length).fill(0),
      material: new Cesium.DynamicWallMaterialProperty({
        color: Cesium.Color.fromCssColorString(color).withAlpha(0.5),
        duration: 3000
      })
    }
  })
  return entity
}

/**
 * 飞线
 * @viewer {*}  视图
 * @item {*} [lon, lat]
 * @returns entity
 */
const renderLineFlow = (viewer, item, { heightNum, speedNum } = { heightNum: 500, speedNum: 1 }) => {
  // 经纬度
  let start_lon = item[0]
  let start_lat = item[1]
  let startPoint = new Cesium.Cartesian3.fromDegrees(start_lon, start_lat, 0)
  // 随机高度
  let height = heightNum * Math.random()
  // 速度
  let endPoint = new Cesium.Cartesian3.fromDegrees(start_lon, start_lat, height)
  let linePositions = []
  linePositions.push(startPoint)
  linePositions.push(endPoint)
  let entity = viewer.entities.add({
    polyline: {
      positions: linePositions,
      material: new Cesium.LineFlowMaterialProperty({
        color: new Cesium.Color(1.0, 1.0, 0.0, 0.8),
        speed: speedNum * Math.random(),
        // speed: 1,
        percent: 0.1,
        gradient: 0.01
      })
    }
  })
  return entity
}

/**
 * 渲染水波纹
 * @param {*} viewer
 * @param {*} item
 * @param {*} height 0
 * @param {*} radius 半径
 * @returns
 */
const renderWaterRipple = (viewer, item, radius) => {
  let circleWave = new CircleWave(viewer, item.id)
  let entity = circleWave.add([item.lng, item.lat, 0], '#1FA8E3', radius, 3000, item)
  return entity
}

/**
 * 楼栋渲染文字label
 * @param {*} viewer
 * @param {*} outline
 * @param {*} height
 * @param {*} label { text: "恒大御景1栋", font: "14px" }
 * @param {*} type   1 楼栋边界  2网格边界
 * @returns
 */
const renderFontLabel = async (viewer, outline, height, label, type) => {
  if (outline && outline.length) {
    //添加文字在指定位置
    let res
    type = type ? type : 1
    if (type == 1) {
      let outlineArr = getOutLine(outline)
      res = getBuildingCenter(outlineArr)
    } else {
      res = await getOutlineCenter(outline)
    }
    let lng = res.lng
    let lat = res.lat
    let entityObj = {
      position: Cesium.Cartesian3.fromDegrees(lng, lat, height),
      type: type == 1 ? 'build-label' : 'grid-label',
      label
    }
    label.id ? entityObj.id = label.id : null
    return viewer.entities.add(entityObj)
  }
}

// 添加单个楼栋label鼠标移入时显示
const addOneLabel = (viewer, x, y, label) => {
  return viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(x, y, 150),
    label
  })
}

// 获取outline中心点
const getBuildingCenter = outlineArr => {
  let lng = 0,
    lat = 0
  let length = outlineArr.length / 2
  outlineArr.map((v, k) => {
    if (k % 2 === 0) {
      lng += v
    } else {
      lat += v
    }
  })
  return { lng: lng / length, lat: lat / length }
}

const getOutlineCenter = outlineArr => {
  return new Promise(resolve => {
    let length = outlineArr.length
    let lng = 0,
      lat = 0
    outlineArr.map(v => {
      lng += v[0]
      lat += v[1]
    })
    resolve({ lng: lng / length, lat: lat / length })
  })
}
// 楼栋经纬度转换(1维数组)
const getOutLine = outline => {
  let outlineArr = JSON.parse(outline)
  let arr = []
  for (let i = 0; i < outlineArr.length; i++) {
    for (let j = 0; j < outlineArr[i].length; j++) {
      var result = gcoord.transform(
        [outlineArr[i][j].lng, outlineArr[i][j].lat], // 经纬度坐标
        gcoord.BD09, // 当前坐标系
        gcoord.WGS84 // 目标坐标系
      )
      arr.push(result[0])
      arr.push(result[1])
    }
  }
  return arr
}

// 网格边界经纬度转化(2维数组)
const getTwoDinOutLine = outline => {
  let outlineArr = JSON.parse(outline)
  let arr = []
  for (let i = 0; i < outlineArr.length; i++) {
    for (let j = 0; j < outlineArr[i].length; j++) {
      let result = gcoord.transform(
        [outlineArr[i][j].lng, outlineArr[i][j].lat], // 经纬度坐标
        gcoord.BD09, // 当前坐标系
        gcoord.WGS84 // 目标坐标系
      )
      let arr2 = [result[0], result[1]]
      arr.push(arr2)
    }
  }
  return arr
}

// 网格边界经纬度转化(2维数组)
const getTwoDinOutLineWithoutGcoord = outline => {
  let outlineArr = JSON.parse(outline)
  let arr = []
  for (let i = 0; i < outlineArr.length; i++) {
    for (let j = 0; j < outlineArr[i].length; j++) {
      let arr2 = [outlineArr[i][j].lng, outlineArr[i][j].lat]
      arr.push(arr2)
    }
  }
  return arr
}

const clearoutlineWall = () => {
  if (window.outlineEntityWalls && window.outlineEntityWalls.length) {
    for (let i = 0; i < window.outlineEntityWalls.length; i++) {
      window.viewer.entities.remove(window.outlineEntityWalls[i])
    }
    window.outlineEntityWalls = []
  }
}

const clearEntityBuilding = () => {
  if (window.EntityBuildings && window.EntityBuildings.length) {
    for (let i = 0; i < window.EntityBuildings.length; i++) {
      window.viewer.entities.remove(window.EntityBuildings[i])
    }
    window.EntityBuildings = []
  }
}

const clearEntityMarker = () => {
  if (window.cesiumMarkerArr) {
    for (let i = 0; i < window.cesiumMarkerArr.length; i++) {
      window.viewer.entities.remove(window.cesiumMarkerArr[i])
    }
    window.cesiumMarkerArr = []
  }
}

const clearEntity = type => {
  if (window[type]) {
    for (let i = 0; i < window[type].length; i++) {
      window.viewer.entities.remove(window[type][i])
    }
    window[type] = []
  }
}

export {
  initMap,
  set3DTilesetHeight,
  map_common_addDatasouce,
  renderCesiumOutline,
  renderLineFlow,
  renderFontLabel,
  renderWaterRipple,
  getOutLine,
  getTwoDinOutLine,
  getTwoDinOutLineWithoutGcoord,
  clearoutlineWall,
  clearEntityBuilding,
  clearEntityMarker,
  clearEntity,
  addOneLabel
}
